﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using GraphViewerWpf.Graph;
using GraphViewer.Data;
using GraphViewerWpf.Entity;
using GraphViewer.Entity;
using GraphViewer.Configuration;

namespace GraphViewerWpf.ViewModels
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        private string layoutAlgorithmType;
        private BidirectionalGraph graph;
        private List<String> layoutAlgorithmTypes = new List<string>();
        private int count;

        private DataLoader _dataLoader;
        private List<Edge> _edges;
        private List<Vertex> _vertices;

        private Vertex AddVertex(string id)
        {
            Vertex vertex = _vertices.Find(v => v.Id == id);

            if (vertex == null)
            {
                vertex = new Vertex(id, NodeType.ActiveProcess);
                _vertices.Add(vertex);
                Graph.AddVertex(vertex);
            }

            return vertex;
        }

        private void AddEdge(string from, string to)
        {
            string id = string.Format("{0}-{1}", from, to);
            Edge edge = _edges.Find(e => e.Id == id);
            Vertex verticeFrom = AddVertex(from);
            Vertex verticeTo = AddVertex(to);

            if (edge == null)
            {
                edge = new Edge(id, verticeFrom, verticeTo);
                _edges.Add(edge);
                Graph.AddEdge(edge);
            }
        }

        public MainWindowViewModel()
        {
            Graph = new BidirectionalGraph(true);

            _dataLoader = new DataLoader();
            _edges = new List<Edge>();
            _vertices = new List<Vertex>();

            _dataLoader.LoadData(EnvironmentConfigurationSection.GetSection().DataBases["ATS-S"].ServerName, "SRC");

            foreach (var process in _dataLoader.Processes)//.Where(g => g.GroupId == "5"))
            {
                AddVertex(process.ProcessId);

                foreach (var predecessor in process.Predecessors)
                {
                    AddEdge(predecessor, process.ProcessId);
                }

                foreach (var successor in process.Successors)
                {
                    AddEdge(process.ProcessId, successor);
                }
            }

            //Graph.AddVertexRange(_vertices);
            //Graph.AddVerticesAndEdgeRange(_edges);

            //List<Vertex> existingVertices = new List<Vertex>();
            //existingVertices.Add(new Vertex("Sacha Barber", NodeType.ActiveProcess)); //0
            //existingVertices.Add(new Vertex("Sarah Barber", NodeType.ActiveProcess)); //1
            //existingVertices.Add(new Vertex("Marlon Grech", NodeType.ActiveProcess)); //2


            //foreach (Vertex vertex in existingVertices)
            //    Graph.AddVertex(vertex);


            ////add some edges to the graph
            //AddNewGraphEdge(existingVertices[0], existingVertices[1]);
            //AddNewGraphEdge(existingVertices[0], existingVertices[2]);

            //Add Layout Algorithm Types
            layoutAlgorithmTypes.Add("BoundedFR");
            layoutAlgorithmTypes.Add("Circular");
            layoutAlgorithmTypes.Add("CompoundFDP");
            layoutAlgorithmTypes.Add("EfficientSugiyama");
            layoutAlgorithmTypes.Add("Sugiyama");
            layoutAlgorithmTypes.Add("FR");
            layoutAlgorithmTypes.Add("ISOM");
            layoutAlgorithmTypes.Add("KK");
            layoutAlgorithmTypes.Add("LinLog");
            layoutAlgorithmTypes.Add("Tree");

            //Pick a default Layout Algorithm Type
            LayoutAlgorithmType = "Tree";
        }

        public void ReLayoutGraph()
        {
            //Graph = new BidirectionalGraph(true);
            //count++;

            //List<Vertex> existingVertices = new List<Vertex>();
            //existingVertices.Add(new Vertex(String.Format("Barn Rubble{0}", count), NodeType.ActiveProcess)); //0
            //existingVertices.Add(new Vertex(String.Format("Frank Zappa{0}", count), NodeType.ActiveProcess)); //1
            //existingVertices.Add(new Vertex(String.Format("Gerty CrinckleBottom{0}", count), NodeType.ActiveProcess)); //2


            //foreach (Vertex vertex in existingVertices)
            //    Graph.AddVertex(vertex);


            ////add some edges to the graph
            //AddNewGraphEdge(existingVertices[0], existingVertices[1]);
            //AddNewGraphEdge(existingVertices[0], existingVertices[2]);

            //NotifyPropertyChanged("Graph");
        }


        public List<String> LayoutAlgorithmTypes
        {
            get { return layoutAlgorithmTypes; }
        }

        public string LayoutAlgorithmType
        {
            get { return layoutAlgorithmType; }
            set
            {
                layoutAlgorithmType = value;
                NotifyPropertyChanged("LayoutAlgorithmType");
            }
        }

        public BidirectionalGraph Graph
        {
            get { return graph; }
            set
            {
                graph = value;
                NotifyPropertyChanged("Graph");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }
}
